package com.example.dormitory_system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dormitory_system.domain.PageQueryDTO;
import com.example.dormitory_system.domain.dto.sysuser.RegisterDTO;
import com.example.dormitory_system.domain.dto.tsysuser.ListDTO;
import com.example.dormitory_system.domain.dto.tsysuser.UserInfoUpdateDTO;
import com.example.dormitory_system.domain.enetiy.User;
import com.example.dormitory_system.domain.vo.student.SysUserListVO;
import com.example.dormitory_system.domain.vo.sysuser.SysLoginVO;
import com.example.dormitory_system.domain.vo.tsysuser.TeacherVO;
import com.example.dormitory_system.domain.vo.tsysuser.UserInfoVO;
import com.example.dormitory_system.domain.vo.tsysuser.UserVO;
import com.example.dormitory_system.domain.vo.user.LoginVO;
import com.example.dormitory_system.enums.ResultCode;
import com.example.dormitory_system.exception.ServiceException;
import com.example.dormitory_system.service.UserService;
import com.example.dormitory_system.mapper.UserMapper;
import com.example.dormitory_system.utils.BCryptUtils;
import com.github.pagehelper.PageHelper;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
* @author keenan
* @description 针对表【tb_user(用户表)】的数据库操作Service实现
* @createDate 2025-03-26 15:31:46
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public SysLoginVO login(String username, String password) {
        // 1. 通过username查询用户
        if (StrUtil.isEmpty(username) || StrUtil.isEmpty(password)) {
            throw new ServiceException(ResultCode.FAILED_LOGIN);
        }

        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));

        // 2. 判断用户是否存在
        if (user == null) {
            throw new ServiceException(ResultCode.FAILED_LOGIN);
        }
        
        // 3. 比较密码是否匹配
        if (!BCryptUtils.matchesPassword(password, user.getPassword())) {
            throw new ServiceException(ResultCode.FAILED_LOGIN);
        }

        // 4. 获取HttpSession并存储用户信息
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpSession session = attributes.getRequest().getSession();
            session.setAttribute("userId",user.getUserId());
            session.setAttribute("role", user.getRole());
        }

        // 5. 返回用户角色
        return new SysLoginVO( user.getUserId(), user.getRole());
    }

    @Override
    public int register(RegisterDTO registerDTO) {
        // 1. 参数校验
        if (StrUtil.isEmpty(registerDTO.getUsername()) || StrUtil.isEmpty(registerDTO.getPassword())) {
            throw new ServiceException(ResultCode.FAILED_PARAMS_VALIDATE);
        }
        if (userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, registerDTO.getUsername())) != null) {
            throw new ServiceException(ResultCode.AILED_USER_EXISTS);
        }

        User user = new User();
        user.setName(registerDTO.getName());
        user.setUsername(registerDTO.getUsername());
        user.setPassword(BCryptUtils.encryptPassword(registerDTO.getPassword()));
        user.setCreateDate(LocalDateTime.now());
        user.setRole(3);
        return userMapper.insert(user);
    }

    @Override
    public List<UserVO> sysListUser(ListDTO listDTO) {
//        String name = listDTO.getName();
//        String username = listDTO.getUsername();
//        if (listDTO == null){
//            return userMapper.selectList(new LambdaQueryWrapper<User>().in(User::getRole,2,3)).stream().map(item -> {
//                UserVO userVO = new UserVO();
//                BeanUtil.copyProperties(item, userVO);
//                return userVO;
//        }).collect(Collectors.toList());}
//
//        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//        queryWrapper.like(name != null, "name", name);
//        queryWrapper.in("role", 2,3);
//        queryWrapper.like(username != null, "username", username);
//        return userMapper.selectList(queryWrapper).stream().map(item -> {
//            UserVO userVO = new UserVO();
//            BeanUtil.copyProperties(item, userVO);
//            return userVO;
//        }).collect(Collectors.toList());
        PageHelper.startPage(listDTO.getPageNum(), listDTO.getPageSize());
        return userMapper.selectUserList(listDTO);
    }

    @Override
    public UserInfoVO sysUserInfo(Long userId) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUserId, userId));
        if (user == null)
            throw new ServiceException(ResultCode.FAILED_USER_NOT_EXISTS);
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtil.copyProperties(user, userInfoVO);
        return userInfoVO;
    }

    @Override
    public int sysUserInfoUpdate(UserInfoUpdateDTO userInfoUpdateDTO) {
        if (userInfoUpdateDTO.getUserId() == null) {
            throw new ServiceException(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        return userMapper.updateUserInfo(userInfoUpdateDTO);
    }

    @Override
    public TeacherVO searchTeacher(String teacherName) {
        List<String> namelist = new ArrayList<>();
        List<Long> idlist = new ArrayList<>();
        TeacherVO teacherVO = new TeacherVO();
        if(teacherName == null){
            List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getRole, 3));
            for (User user : userList) {
                namelist.add(user.getUsername());
                idlist.add(user.getUserId());
            }
            teacherVO.setId(idlist);
            teacherVO.setName(namelist);
            return teacherVO;
        }
        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getRole, 3).like(User::getUsername, teacherName));
        for (User user : userList) {
            namelist.add(user.getUsername());
            idlist.add(user.getUserId());
        }
        teacherVO.setId(idlist);
        teacherVO.setName(namelist);
        return teacherVO;
}



    @Override
    public Boolean resetpassoword(Long userId,String oldPassword,String newPassword) {
        if(userId == null || userId<0){
            throw new ServiceException(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        User user = this.getById(userId);
        String userPassword = user.getPassword();
        if(!BCryptUtils.matchesPassword(oldPassword, userPassword)){
            throw new ServiceException(ResultCode.FAILED_PARAMS_VALIDATE);
        }
        user.setPassword(BCryptUtils.encryptPassword(newPassword));
        return this.updateById(user);
    }

    @Override
    public int deleteUser(Long userId) {
        return userMapper.deleteById(userId);
    }

    @Override
    public List<SysUserListVO> listUser(String name) {
//        if (StrUtil.isEmpty(name)) {
//            return userMapper.selectList(new LambdaQueryWrapper<User>().select(User::getUserId, User::getName)).stream().map(item -> {
//                SysUserListVO sysUserListVO = new SysUserListVO();
//                BeanUtil.copyProperties(item, sysUserListVO);
//                return sysUserListVO;
//            }).collect(Collectors.toList());
//        }
        return userMapper.selectByName(name);
//        String newName = name.replace(" ", "");
//        return userMapper.selectList(new LambdaQueryWrapper<User>().select(User::getUserId, User::getName).like(User::getName, name)).stream().map(item -> {
//            SysUserListVO sysUserListVO = new SysUserListVO();
//            BeanUtil.copyProperties(item, sysUserListVO);
//            return sysUserListVO;
//        }).collect(Collectors.toList());
    }
}